package com.lenovo.lcdmoauth.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.lenovo.lcdmoauth.model.Group;
import com.lenovo.lcdmoauth.model.User;
import com.lenovo.lcdmoauth.model.UserGroup;
import com.lenovo.lcdmoauth.service.GroupService;
import com.lenovo.lcdmoauth.service.UserGroupService;
import com.lenovo.lcdmoauth.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class UserDetailServiceImpl implements UserDetailsService {

    private final UserService userService;

    private final UserGroupService userGroupService;

    private final GroupService groupService;

    @Autowired
    public UserDetailServiceImpl(UserService userService, UserGroupService userGroupService, GroupService groupService) {
        this.userService = userService;
        this.userGroupService = userGroupService;
        this.groupService = groupService;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<User> otl = new LambdaQueryChainWrapper<>(userService.getBaseMapper()).apply("deleted = 0 and LOWER(it_code) = {0}", StringUtils.lowerCase(username)).list().stream().findFirst();

        if (!otl.isPresent()) {
            throw new UsernameNotFoundException("username not found");
        }
        User user = otl.get();
        List<UserGroup> list = new LambdaQueryChainWrapper<>(userGroupService.getBaseMapper()).eq(UserGroup::getUserId, user.getId()).list();
        List<Long> groupIds = list.stream().map(UserGroup::getGroupId).toList();
        List<Group> groups = new LambdaQueryChainWrapper<>(groupService.getBaseMapper()).in(Group::getId, groupIds).list();
        List<SimpleGrantedAuthority> authorities = groups.stream().map(group -> new SimpleGrantedAuthority(group.getGroupName())).toList();
        return new org.springframework.security.core.userdetails.User(user.getItCode(), "1", authorities);
    }
}
